﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "appmonitortaskmanager.h"
#include <QMessageBox>
#include "appmonitorwidget.h"
#include "appmonitorlogwidget.h"
#include "syscfg.h"
#include "systemmonitormanager.h"
#include "sysmonitorlogwidget.h"
#include "StatusReporterTask.h"
#include "TcpServer.h"


void MainWindow::checkSysRegErrorReportDontOpenUI()
{
    int sysRegValue = getSysRegErrorReportDontOpenUI();
    if(sysRegValue < 0)
    {
        LOG_ERROR("try to getSysRegErrorReportOpenUI failed");
        QMessageBox::warning(this, "提示", "尝试获取系统应用crash弹框注册表信息失败");
    }
    else if(sysRegValue == 0)
    {
        if(QMessageBox::Yes == QMessageBox::information(this, "提示", "检查到系统打开了应用crash弹框调试设置,是否关闭?",QMessageBox::Yes | QMessageBox::No))
        {
            updateSysRegErrorReportDontOpenU(1);
            ui->changeAppErrorReportSettingButton->setText("打开弹窗调试");
        }
        else
        {
            ui->changeAppErrorReportSettingButton->setText("关闭弹窗调试");
        }
    }
    else
    {
        ui->changeAppErrorReportSettingButton->setText("打开弹窗调试");
    }
}

void MainWindow::checkAutoStart()
{
    bool autoStart = isSelfAutoStart();
    if(!autoStart)
    {

        if(QMessageBox::Yes == QMessageBox::information(this, "提示", "是否开起开机自启动",QMessageBox::Yes | QMessageBox::No))
        {
            if (f_success == setSelfAutoStart(true))
            {
                ui->autoStartRadioButton->setChecked(true);
            }
            else
            {
                ui->autoStartRadioButton->setChecked(false);
                QMessageBox::warning(this, "提示", "设置开机自启动失败,请确认当前程序是否有权限访问:C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\");
            }

        }
        else
        {
           ui->autoStartRadioButton->setChecked(false);
        }
    }
    else
    {
        ui->autoStartRadioButton->setChecked(true);
    }
}

void MainWindow::initSysSettingView()
{
    checkSysRegErrorReportDontOpenUI();

    checkAutoStart();

    ui->cpuAlarmThresHoldLineEdit->setText(int2QStr(CPU_ALARM_THRESHOLD));
    ui->cpuCheckIntervalSecondsLineEdit->setText(int2QStr(CPU_CHECK_INTERVAL_SECONDS));

    ui->memAlarmThresholdLineEdit->setText(int2QStr(MEM_ALARM_THRESHOLD));
    ui->memCheckIntervalSecondLineEdit->setText(int2QStr(MEM_CHECK_INTERVAL_SECONDS));

    ui->diskAlarmThresHoldLineEdite->setText(int2QStr(DISK_ALARM_THRESHOLD));
    ui->diskCheckIntrvalSecondsLineEdite->setText(int2QStr(DISK_CHECK_INTERVAL_SECONDS));

    ui->watchDogServerIPLineEdite->setText(WATCHDOG_SERVER_IP);
    ui->watchDogServerPortLineEdite->setText(int2QStr(WATCHDOG_SERVER_PORT));

    ui->listenSocketLineEdite->setText(int2QStr(LISTEN_PORT));
}

void MainWindow::diskUsageUpdated()
{
    static list<QWidget *> diskBGWidgets = list<QWidget *>();

    SafeClearListAndDelEle(QWidget, diskBGWidgets);

    static QLabel *alarmLabel = new QLabel(ui->DiskInfoView);
    alarmLabel->setText("硬盘告警阀值为 "+ float2QStr(DISK_ALARM_THRESHOLD) +"%");
    alarmLabel->setGeometry(QRect(20,430,160,20));
    alarmLabel->show();

    list<DiskInfo>::iterator diskItor;
    diskItor = gSystemMonitorManger.lastDiskInfo.begin();

    int diskIndex = 0;
    for(;diskItor!=gSystemMonitorManger.lastDiskInfo.end();++diskItor)
    {
         int widgetHeight = 420/gSystemMonitorManger.lastDiskInfo.size();
         int widgetY = diskIndex *widgetHeight +10;
         diskIndex++;

         QWidget * diskBGWidget =  new QWidget(ui->DiskInfoView);
         diskBGWidgets.push_back(diskBGWidget);
         diskBGWidget->setGeometry(QRect(10, widgetY, 180, widgetHeight-10));
         diskBGWidget->setStyleSheet(QStringLiteral("background-color: rgb(240, 240, 240);"));
         diskBGWidget->show();

         QLabel *diskNameLabel = new QLabel(diskBGWidget);
         diskNameLabel->setText("本地磁盘"+diskItor->disk);
         diskNameLabel->setGeometry(QRect(10,0,170,(widgetHeight-10)/3));
         diskNameLabel->setStyleSheet(QStringLiteral("background-color: rgb(240, 240, 240);"));
         diskNameLabel->show();

         QProgressBar *diskBar = new QProgressBar(diskBGWidget);
         diskBar->setValue((1-diskItor->freeMB/diskItor->totalMB )*100);
         diskBar->setGeometry(QRect(10,(widgetHeight-10)/3,160,(widgetHeight-10)/3));
         if(diskBar->value()>DISK_ALARM_THRESHOLD){
             QPalette pe;
             pe.setColor(QPalette::WindowText,Qt::red);
             diskBar->setPalette(pe);
         }
//         diskBar->setTextVisible(false);
             diskBar->show();

         QLabel *diskUsageLabel = new QLabel(diskBGWidget);
         QString freeMB = float2QStr((int)diskItor->freeMB/1024);
         QString totalMB = float2QStr((int)diskItor->totalMB/1024);
         diskUsageLabel->setText(freeMB+"GB可用,共"+totalMB+ "GB");
         diskUsageLabel->setGeometry(QRect(10,(widgetHeight-10)*2/3,170,(widgetHeight-10)/3));
         QPalette pa;
         pa.setColor(QPalette::WindowText,Qt::darkGray);
         diskUsageLabel->setPalette(pa);
         diskUsageLabel->show();

    }


}

void MainWindow::memUsageUpdated()
{
    if(ui->MemInfoView->graphCount() == 0)
    {
        ui->MemInfoView->addGraph();
        ui->MemInfoView->addGraph();
        ui->MemInfoView->xAxis->setLabel("最近20次内存(红色表示告警阀值)");
        ui->MemInfoView->yAxis->setLabel("占用率(%)");
        ui->MemInfoView->xAxis->setRange(1, 20);
        ui->MemInfoView->yAxis->setRange(1, 100);
    }

    int limitMemValue = MEM_ALARM_THRESHOLD;

    QVector<double> limitX(21), limitY(21);
    for(int i = 0;i<21;i++)
    {
        limitX[i] = i;
        limitY[i] = limitMemValue;
    }
    ui->MemInfoView->graph(0)->setPen(QPen(Qt::red));
    ui->MemInfoView->graph(0)->setData(limitX,limitY);


    int memChartIndex = 0;

    list<MEMORYSTATUSEX>::iterator memItor;

    memItor = gSystemMonitorManger.lastMEMUsages.begin();

    QVector<double> x(gSystemMonitorManger.lastMEMUsages.size()), y(gSystemMonitorManger.lastMEMUsages.size());

    for(;memItor!=gSystemMonitorManger.lastMEMUsages.end();++memItor)
    {
        x[memChartIndex] = memChartIndex+1;
        y[memChartIndex] = memItor->dwMemoryLoad+1;
        memChartIndex++;

    }


    ui->MemInfoView->graph(1)->setData(x, y, true);
    ui->MemInfoView->replot();

}

void MainWindow::cpuUsageUpdated()
{

    if(ui->CPUInfoView->graphCount() == 0)
    {
        ui->CPUInfoView->addGraph();
        ui->CPUInfoView->addGraph();
        ui->CPUInfoView->xAxis->setLabel("最近20次CPU(红色表示告警阀值)");
        ui->CPUInfoView->yAxis->setLabel("占用率(%)");
        ui->CPUInfoView->xAxis->setRange(1, 20);
        ui->CPUInfoView->yAxis->setRange(1, 100);
    }

    int limitCPUValue = CPU_ALARM_THRESHOLD;

    QVector<double> limitX(21), limitY(21);
    for(int i = 0;i<21;i++)
    {
        limitX[i] = i;
        limitY[i] = limitCPUValue;
    }
    ui->CPUInfoView->graph(0)->setPen(QPen(Qt::red));
    ui->CPUInfoView->graph(0)->setData(limitX,limitY);

    int cpuChartIndex = 0;

    list<double>::iterator cpuItor;

    cpuItor = gSystemMonitorManger.lastCPUUsages.begin();

    QVector<double> x(gSystemMonitorManger.lastCPUUsages.size()), y(gSystemMonitorManger.lastCPUUsages.size());

    for(;cpuItor!=gSystemMonitorManger.lastCPUUsages.end();++cpuItor)
    {
        LOG_INFO("CPUUSED:%f", *cpuItor);
        x[cpuChartIndex] = cpuChartIndex+1;
        y[cpuChartIndex] = *cpuItor+1;
        cpuChartIndex++;

    }


    ui->CPUInfoView->graph(1)->setData(x, y, true);
    ui->CPUInfoView->replot();
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    appMonitorLogCount = 0;

    sysMonitorLogCount = 0;

    ui->setupUi(this);

    initSysSettingView();

    int i = 0;
    ui->appMonitorTable->setColumnWidth(i++, 100);
    ui->appMonitorTable->setColumnWidth(i++, 150);
    ui->appMonitorTable->setColumnWidth(i++, 150);
    ui->appMonitorTable->setColumnWidth(i++, 100);
    ui->appMonitorTable->setColumnWidth(i++, 70);
    ui->appMonitorTable->setColumnWidth(i++, 200);
    ui->appMonitorTable->setColumnWidth(i++, 200);
    ui->appMonitorTable->setColumnWidth(i++, 40);

    connect(&gAppMonitorTaskManager, SIGNAL(taskChanged()), this, SLOT(freshAppMonitor()));
    connect(&gAppMonitorTaskManager, SIGNAL(appRestarted()), this, SLOT(onMonitorLogIncrease()));
    connect(ui->appMonitorTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(onItemClicked(QTableWidgetItem*)));
    connect(ui->appMonitorTable, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(onItemDoubleClicked(QTableWidgetItem*)));
    connect(ui->createButton, SIGNAL(clicked(bool)), this, SLOT(onCreateButtonClicked()));
    connect(ui->quitButton, SIGNAL(clicked(bool)), this, SLOT(close()));
    connect(ui->logButton, SIGNAL(clicked(bool)),this, SLOT(onShowMonitorLogLicked()));
    connect(ui->changeAppErrorReportSettingButton, SIGNAL(clicked(bool)), this, SLOT(changeSysRegErrorReportDontOpenUISetting()));
    connect(ui->autoStartRadioButton, SIGNAL(clicked(bool)), this, SLOT(changeAutoStartSetting(bool)));

    connect(&gSystemMonitorManger, SIGNAL(diskUsageUpdated()), this, SLOT(diskUsageUpdated()));
    connect(&gSystemMonitorManger, SIGNAL(memUsageUpdated()), this, SLOT(memUsageUpdated()));
    connect(&gSystemMonitorManger, SIGNAL(cpuUsageUpdated()), this, SLOT(cpuUsageUpdated()));
    connect(&gSystemMonitorManger, SIGNAL(onSysMonitorAlarmFired()), this, SLOT(onSysMonitorLogIncrease()));
    connect(&gStatusReporter, SIGNAL(reportStatusStateChanged(int)), this, SLOT(onReportStatusStateChanged(int)));

    freshAppMonitor();

    gAppMonitorTaskManager.startNoStopFlagTasks();
    gSystemMonitorManger.startAllTask();

    gStatusReporterTask.run();

    TcpServer * server = new TcpServer(LISTEN_PORT);
    server->run();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updateLogButtonText()
{
    ui->logButton->setText( "启动日志(" +int2QStr(appMonitorLogCount) + "条未读)");
}

void MainWindow::updateSysAlertLogButtonText()
{
    ui->sysAlertLogButton->setText( "告警日志(" +int2QStr(sysMonitorLogCount) + "条未读)");
}

void MainWindow::freshAppMonitor()
{

    list<AppMonitorTask *> & tasks = gAppMonitorTaskManager.tasks;
    if(tasks.size() == ui->appMonitorTable->rowCount())
    {
        int y = 0;
        foreach (AppMonitorTask * task, tasks) {
            int i = 0;
            ui->appMonitorTable->item(y,i++)->setText(task->appMonitor.name);
            ui->appMonitorTable->item(y,i++)->setText(task->appMonitor.getTypeName());
            ui->appMonitorTable->item(y,i++)->setText(task->appMonitor.cfgInfo);
            ui->appMonitorTable->item(y,i++)->setText(int2QStr(task->appMonitor.maxMemLimitKB/1024));
            ui->appMonitorTable->item(y,i++)->setText(int2QStr(task->appMonitor.checkIntervalSeconds));
            ui->appMonitorTable->item(y,i++)->setText(task->appMonitor.startCmd);
            ui->appMonitorTable->item(y,i++)->setText(task->sayState());

            QTableWidgetItem* item4;
            if(task->state == RunableStateStarted)
            {

                item4 = ui->appMonitorTable->item(y,i++);
                item4->setText(QString("停止"));
                item4->setIcon(QIcon(":/new/icon/ui/stop.png"));
            }
            else
            {
                item4 = ui->appMonitorTable->item(y,i++);
                item4->setText(QString("启动"));
                item4->setIcon(QIcon(":/new/icon/ui/start.png"));
            }

            y++;
        }
    }
    else
    {
        ui->appMonitorTable->clearContents();
        ui->appMonitorTable->setRowCount(tasks.size());
        int y = 0;
        foreach (AppMonitorTask * task, tasks) {
            int i = 0;
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(task->appMonitor.name));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(task->appMonitor.getTypeName()));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(task->appMonitor.cfgInfo));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(int2QStr(task->appMonitor.maxMemLimitKB)));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(int2QStr(task->appMonitor.checkIntervalSeconds)));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(task->appMonitor.startCmd));
            ui->appMonitorTable->setItem(y,i++,  new QTableWidgetItem(task->sayState()));

            QTableWidgetItem* item4;
            if(task->state == RunableStateStarted)
            {
                item4 = new QTableWidgetItem(QIcon(":/new/icon/ui/stop.png"), QString("停止"));
            }
            else
            {
                item4 = new QTableWidgetItem(QIcon(":/new/icon/ui/start.png"), QString("启动"));
            }
            ui->appMonitorTable->setItem(y,i++, item4);
            y++;
        }
    }
}

void MainWindow::onItemClicked(QTableWidgetItem *item)
{
    int row = item->row();
    int colum = item->column();
    if(colum == 7)
    {
        AppMonitorTask * task =  gAppMonitorTaskManager.getTaskByIndex(row);
        if(task == NULL)
        {
            QMessageBox::warning(this, "异常", "获取任务信息失败");
        }
        else
        {
            if(task->state == RunableStateStoped)
            {
                if(QMessageBox::Yes == QMessageBox::information(NULL, "提示", "确认要启动该监听吗?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
                {
                    gAppMonitorTaskManager.startTask(task);

                }
            }
            else
            {

                QMessageBox messageBox(QMessageBox::Warning,    "提示", "请选择停止的方式?",
                                         QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::Cancel, NULL);
                messageBox.setButtonText(QMessageBox::Yes, "只停止监控");
                messageBox.setButtonText(QMessageBox::YesToAll, "同时停止监控以及程序");
                messageBox.setButtonText(QMessageBox::Cancel, "取消");

//                if(QMessageBox::Yes == QMessageBox::information(NULL, "提示", "确认要停止该监听吗?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
//                {
//                    gAppMonitorTaskManager.stopAndWaitTask(task);
//                }

                if(QMessageBox::Yes == messageBox.exec())
                {
                    gAppMonitorTaskManager.stopAndWaitTask(task);
                }
                else if (QMessageBox::YesToAll == messageBox.exec())
                {
                    gAppMonitorTaskManager.stopAndWaitTask(task, true);
                }
            }
        }

        freshAppMonitor();
    }

}


void MainWindow::onItemDoubleClicked(QTableWidgetItem* item)
{

    int row = item->row();
    AppMonitorTask * task =  gAppMonitorTaskManager.getTaskByIndex(row);

    AppMonitorWidget * win = new AppMonitorWidget(this);
    win->prepareUpdateAppMointor(task->appMonitor);
    win->exec();

    freshAppMonitor();
}

void MainWindow::onCreateButtonClicked()
{
    AppMonitorWidget * win = new AppMonitorWidget(this);
    win->prepareCreateAppMointor();
    win->exec();
    freshAppMonitor();
}

void MainWindow::onShowMonitorLogLicked()
{
    AppMonitorLogWidget * win = new AppMonitorLogWidget(this);
    win->setModal(false);
    win->show();
    appMonitorLogCount = 0;
    updateLogButtonText();
}

void MainWindow::onMonitorLogIncrease()
{
    appMonitorLogCount += 1;
    updateLogButtonText();
}

void MainWindow::onSysMonitorLogIncrease()
{
    sysMonitorLogCount += 1;
    updateSysAlertLogButtonText();
}

void MainWindow::changeSysRegErrorReportDontOpenUISetting()
{
    int sysRegValue = getSysRegErrorReportDontOpenUI();
    if(sysRegValue < 0)
    {
        LOG_ERROR("try to getSysRegErrorReportOpenUI failed");
        QMessageBox::warning(this, "提示", "尝试获取系统应用crash弹框注册表信息失败");
    }
    else if(sysRegValue == 0)
    {
        updateSysRegErrorReportDontOpenU(1);
        ui->changeAppErrorReportSettingButton->setText("打开弹窗调试");
    }
    else
    {
         if(QMessageBox::Yes == QMessageBox::warning(this, "提示", "crash应用被窗口调试时, 应用无法被自动拉起, 确认打开该设置吗?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
         {
             updateSysRegErrorReportDontOpenU(0);
             ui->changeAppErrorReportSettingButton->setText("关闭弹窗调试");
         }
    }
}

void MainWindow::changeAutoStartSetting(bool autoStart)
{
    LOG_INFO("change autoStart to:%s",boolToYesOrNo(autoStart));
    if(autoStart == false &&  QMessageBox::No == QMessageBox::warning(this, "提示", "确认取消开机启动吗?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
    {
        ui->autoStartRadioButton->setChecked(true);
        return;
    }
    if(f_success == setSelfAutoStart(autoStart))
    {
        ui->autoStartRadioButton->setChecked(autoStart);
    }
    else
    {
        QMessageBox::warning(this, "警告", "修改开机启动失败,请确认当前程序是否有管理员权限");
        ui->autoStartRadioButton->setChecked(!autoStart);
    }

}

void MainWindow::onReportStatusStateChanged(int state)
{
    if(state == ReportStatusState_connected)
    {
        ui->statusLightWidget->setStyleSheet("QWidget{border-image: url(:/new/images/images/green.png);}");
        ui->statusLabel->setText("连接成功");
    }
    else if (state == ReportStatusState_offlineWorkMode)
    {
        ui->statusLightWidget->setStyleSheet("QWidget{border-image: url(:/new/images/images/green.png);}");
        ui->statusLabel->setText("离线工作模式");
    }
    else if(state == ReportStatusState_disconnect)
    {
        ui->statusLightWidget->setStyleSheet("QWidget{border-image: url(:/new/images/images/red.png);}");
        ui->statusLabel->setText("连接失败,等待重试...");
    }

    else
    {
        ui->statusLightWidget->setStyleSheet("QWidget{border-image: url(:/new/images/images/orange.png);}");
        ui->statusLabel->setText("连接中...");
    }
}


void MainWindow::on_memAlarmThresholdLineEdit_editingFinished()
{
    QString memAlarmThresHold = ui->memAlarmThresholdLineEdit->text();
    SAVE_MEM_ALARM_THRESHOLD(memAlarmThresHold.toInt());
    gSystemMonitorManger.restartMemoryTask();

}


void MainWindow::on_memCheckIntervalSecondLineEdit_editingFinished()
{
    SAVE_MEM_CHECK_INTERVAL_SECONDS(ui->memCheckIntervalSecondLineEdit->text().toInt());
    gSystemMonitorManger.restartMemoryTask();
}


void MainWindow::on_cpuAlarmThresHoldLineEdit_editingFinished()
{
    SAVE_CPU_ALARM_THRESHOLD(ui->cpuAlarmThresHoldLineEdit->text().toInt());
    gSystemMonitorManger.restartCPUTask();
}




void MainWindow::on_cpuCheckIntervalSecondsLineEdit_editingFinished()
{
    SAVE_CPU_CHECK_INTERVAL_SECONDS(ui->cpuCheckIntervalSecondsLineEdit->text().toInt());
    gSystemMonitorManger.restartCPUTask();

}

void MainWindow::on_diskAlarmThresHoldLineEdite_editingFinished()
{
    SAVE_DISK_ALARM_THRESHOLD(ui->diskAlarmThresHoldLineEdite->text().toInt());
    gSystemMonitorManger.restartDiskTask();

}

void MainWindow::on_diskCheckIntrvalSecondsLineEdite_editingFinished()
{
    SAVE_DISK_CHECK_INTERVAL_SECONDS(ui->diskCheckIntrvalSecondsLineEdite->text().toInt());
    gSystemMonitorManger.restartDiskTask();

}

void MainWindow::on_watchDogServerIPLineEdite_editingFinished()
{
    SAVE_WATCHDOG_SERVER_IP(ui->watchDogServerIPLineEdite->text());
}


void MainWindow::on_watchDogServerPortLineEdite_editingFinished()
{
    SAVE_WATCHDOG_SERVER_PORT(ui->watchDogServerPortLineEdite->text().toInt());
}

void MainWindow::on_sysAlertLogButton_clicked()
{
    SysMonitorLogWidget *win = new SysMonitorLogWidget();
    win->setModal(false);
    win->show();
    sysMonitorLogCount = 0;
    updateSysAlertLogButtonText();
}



void MainWindow::on_listenSocketLineEdite_editingFinished()
{
    SAVE_LISTEN_PORT(ui->listenSocketLineEdite->text().toInt());
}

void MainWindow::on_logButton_clicked()
{

}
